from datetime import datetime, timedelta
import pytest
from .send_to_dd import run


class TestRunData:
    def __init__(self):
        self.passed = 0
        self.failed = 0
        self.skipped = 0

        self.start_time = None
        self.end_time = None
        self.duration = None

        self.order_testcases = []
        self.test_count = 0

        self.notification = ''
        self.passed_ratio = 0.0


def pytest_addoption(parser):
    parser.addoption(
        "--testcases",
        action="store",
        default="",
        help="指定要运行的测试用例列表，用逗号分隔，如：test_001,test_002"
    )
    parser.addoption(
        "--notification",
        action="store",
        default="",
        help="指定通知方式，如：feishu（飞书）、email（邮件）"
    )


def pytest_configure(config):
    config._test_data = TestRunData()
    test_data = config._test_data
    # 用例开始时间
    test_data.start_time = datetime.now()
    # 获取传参
    testcases = config.getoption("testcases")
    if not testcases:
        pytest.exit("执行的用例为空，终止！")
    test_data.order_testcases = testcases.split(",")
    test_data.notification = config.getoption("notification")


def pytest_collection_finish(session):
    # 匹配用例, 通过session.config
    test_data = session.config._test_data
    for index, item in enumerate(list(session.items)):
        if item.originalname not in test_data.order_testcases:
            session.items.pop(index)
        else:
            test_data.order_testcases.remove(item.originalname)
    test_data.test_count = len(session.items)


def pytest_runtest_logreport(report):
    if hasattr(report, 'item'):
        test_data = report.item.config._test_data
        if report.when == "call":
            # print(report.outcome)
            if report.outcome == "passed":
                test_data.passed += 1
            elif report.outcome == "failed":
                test_data.failed += 1
            elif report.outcome == "skipped":
                test_data.skipped += 1


def pytest_unconfigure(config):
    test_data = config._test_data
    test_data.end_time = datetime.now()
    test_data.duration = test_data.end_time - test_data.start_time

    if test_data.test_count > 0:
        test_data.passed_ratio = round(test_data.passed / test_data.test_count, 4)
    # 单元测试
    # assert timedelta(seconds=2) < duration <timedelta(seconds=4)
    # assert my_data["test_count"] == 3
    # assert my_data["passed"] == 2
    # assert my_data["failed"] == 1
    # assert my_data["passed_ratio"] == 0.6667

    # 构造发送信息
    st = test_data.start_time.strftime('%Y-%m-%d %H:%M:%S')
    ed = test_data.end_time.strftime('%Y-%m-%d %H:%M:%S')
    dr = str(test_data.duration).split(".")[0]
    ratio = str(test_data.passed_ratio * 100)
    unmatch = ", ".join(test_data.order_testcases)
    msg = f"""pytest_res:
            执行开始时间：{st}
            执行结束时间：{ed}
            执行总耗时： {dr}
            总用例个数：{test_data.test_count}
            未匹配用例：{unmatch}
            通过率:{ratio}%
    """
    if test_data.notification:
        run(msg=msg)
        print(msg)
    # print(f"{datetime.now()} pytest 用例执行完毕")
